#include "constants.h"

If (isServer) then {
	private ["_parameters","_eligible_towns","_vehicles","_start_pos","_player_close","_i","_car","_base","_allcars","_car_array","_truck_array"];
	_parameters = [d_map_locations];
	_parameters set [count _parameters, [XF_MAP_LOCATION_TYPE,"IN",[XF_MAP_LOCATION_TYPE_TOWN,XF_MAP_LOCATION_TYPE_VILLAGE,XF_MAP_LOCATION_TYPE_LONELY,XF_MAP_LOCATION_TYPE_INDUSTRIAL]]];
	_eligible_towns = _parameters call XfTableFilter;	
	
	_car_array = [];
	_truck_array = [];
	_all_array = [];
	_allcars = configFile >> "CfgVehicles";
	for "_i" from 1 to ((count _allcars) - 1) do {
		_base = configFile >> "CfgVehicles";
		_car = (_base select _i);
		_class = (getText(_car >> "vehicleclass"));
		_scope = (getNumber(_car >> "scope"));
		if (_class == "Car" && _scope == 2) then {
			_faction = toupper(getText(_car >> "faction"));
			if (_faction == "CIV") then {
				if !(configName(_car) isKindOf "Truck") then {
					_car_array set [count _car_array, (configName(_car))];
				} else {
					_truck_array set [count _truck_array, (configName(_car))];
				};
			};
		};
	};
	_all_array = [_all_array, _car_array] call XfArrayPushStack;
	_all_array = [_all_array, _truck_array] call XfArrayPushStack;
	
	if (d_global_debug > 9) then { diag_log Format["(%1)[%2]: %3: towns:%4  vecs:%5",diag_tickTime,"spawnvehicles.sqf","Starting Loop",count _eligible_towns, count _all_array]; };
		
	_vehicles = [];
	While {true} do {
		if (count _vehicles > 0) then {
			for [{_i = 0},{_i < count _vehicles},{_i = _i + 1}] do {
				_vehicle = _vehicles select _i;
				_start_pos = _vehicle getVariable "spawn_start_pos";
				if (!isnil "_start_pos") then {
					if (((getPos _vehicle) distance _start_pos) > 500) then {
						_player_close = false;
						{
							if ((_vehicle distance _x) < 500) then { _player_close = true; };
							sleep (0.5 + (random 0.5));
						} foreach playableunits;
						if (!_player_close) then {
							deleteVehicle _vehicle;
							if (d_global_debug > 9) then { diag_log Format["(%1)[%2]: %3: %4 (%5, %6)",diag_tickTime,"spawnvehicles.sqf","Delete Vehicle",_vehicle, (getPos _vehicle),((getPos _vehicle) distance _start_pos)];};
							_vehicles set [_i, "xXdelXx"];
						};
					};
				} else {
					_vehicle setVariable ["spawn_start_pos", (getPos _vehicle)];
				};
				sleep (0.5 + (random 0.5));
			};
			_vehicles = _vehicles - ["xXdelXx"];
			sleep (120 + random 120);
		};
		sleep (10 + random 10);
		{
			_center = _x select XF_MAP_LOCATION_CENTER;
			_name = _x select XF_MAP_LOCATION_DISPLAYNAME;
			if (d_global_debug > 9) then { diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"spawnvehicles.sqf","Starting Town",_name, _center];};
			
			_player_close = false;
			{
				if ((_center distance _x) < 800) then { _player_close = true; };
				sleep (0.5 + (random 0.5));
			} foreach playableunits;
			
			if (!_player_close) then {
				_cars = nearestObjects [_center, _all_array, 500];
				_houses = nearestObjects [_center, ["House"], 500];
				_amount = (count _houses) / 25;
				_minimal_amount = _amount / 2;
				if (_amount < 1) then {
					// Random chance to spawn a vehicle if the amount is between 0.1 and 1.
					if ((_amount > 0) && (random(1) <= _amount)) then {
						_amount = 1;
					};
				} else {
					_amount = round((_amount / 2) + random (_amount / 2));
				};
				// We remove the amount of cars already present.
				_amount = _amount - (count _cars);
				if (d_global_debug > 9) then { diag_log Format["(%1)[%2]: %3: %4, %5, %6",diag_tickTime,"spawnvehicles.sqf","Cars amounts",_amount, _minimal_amount, (count _cars)];};
				// We check that we can still add cars and that the number of cars in the town has dropped below the minimum
				if ((_amount > 0) && (_minimal_amount > (count _cars)) ) then {
					_location_type = _x select XF_MAP_LOCATION_TYPE;
					_spawn_vecs = _car_array;
					// If it is an industrial site, we'll spawn trucks instead
					if (_location_type in [XF_MAP_LOCATION_TYPE_INDUSTRIAL]) then {
						_spawn_vecs = _truck_array;
					};
					_empty_spot = [];
					if (d_global_debug > 10) then { diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"spawnvehicles.sqf","Spawning",_amount, _spawn_vecs];};
					For [{_i = 0},{_i < _amount},{_i = _i + 1}] do {
						_found = false;
						_tries = 10;
						_road = objNull;
						_vec_type = _spawn_vecs call XfRandomArrayVal;
						if (d_global_debug > 10) then { diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"spawnvehicles.sqf","Spawning",_vec_type, sizeOf _vec_type];};
						while {!_found && _tries > 0} do {
							_empty_spot = [];
							// We pick a random house in those of the area
							_house = _houses call XfRandomArrayVal;
							// We search a road near it.
							_roads = _house nearRoads 20;
							// We pick a random road
							if (count _roads > 0) then {
								// diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"spawnvehicles.sqf","Roads",count _roads, getPos _house];
								// We search a point near this road which is at least 2m away from all roads.
								_tries2 = 30;
								while {count _empty_spot == 0 && _tries2 > 0} do {
									_road = _roads call XfRandomArrayVal;
									_empty_spot = [(getPos _road), 12, 3] call XfGetRanPointCircle;
									if (count _empty_spot == 3) then {
										_empty_spot = _empty_spot findEmptyPosition[0,3,_vec_type];
									};
									_invalid = false;
									if (count _empty_spot == 3) then {
										if (d_global_debug > 10) then {
											// diag_log Format["(%1)[%2]: %3: %4 %5",diag_tickTime,"spawnvehicles.sqf","Testing",_tries2, _empty_spot];
											_mrk_name = Format["mrk_vec_pos_%1%2%3",count _vehicles,_i,_tries2];
											createMarkerLocal [_mrk_name, _empty_spot];
											_mrk_name setMarkerAlphaLocal 0.8;
											_mrk_name setMarkerShapeLocal "ICON";
											_mrk_name setMarkerColorLocal "ColorOrange";
											_mrk_name setMarkerTypeLocal "mil_triangle";
											_mrk_name setMarkerSizeLocal [0.6, 0.6];
										};
										_min_dist = 4 + ((sizeOf _vec_type) / 2);
										if (_min_dist > 10) then {_min_dist = 10};
										{
											if ((_empty_spot distance _x) < _min_dist) exitwith {_invalid = true;};
										} foreach (_empty_spot nearRoads 30);					
									};
									if (_invalid) then {_empty_spot = [];};
									_tries2 = _tries2 - 1;
									sleep 0.123;
								};
								if (count _empty_spot == 3) then { _found = true; };
								_tries = _tries - 1;
							};
							sleep 0.231;
						};
						if (_found && (count _empty_spot == 3)) then {
							if (d_global_debug > 9) then {
								diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"spawnvehicles.sqf","FOUND SPOT",_empty_spot];
								_mrk_name = Format["mrk_vec_%1%2%3",_vec_type,_i,count _vehicles];
								createMarkerLocal [_mrk_name, _empty_spot];
								_mrk_name setMarkerAlphaLocal 0.7;
								_mrk_name setMarkerShapeLocal "ICON";
								_mrk_name setMarkerColorLocal "ColorRed";
								_mrk_name setMarkerTypeLocal "mil_triangle";
								_mrk_name setMarkerSizeLocal [0.6, 0.6];
								_mrk_name setMarkerTextLocal _vec_type;
							};
							// We increase the height so the vehicle "falls" on the ground and looks more natural :)
							_empty_spot set [2, (_empty_spot select 2) + 0.7];
							_vehicle = _vec_type createVehicle _empty_spot;
							_vehicle setDir random(360);
							_vehicle setVariable ["spawn_start_pos", (getPos _vehicle)];
						};
						sleep 0.321;
					};
				};
				sleep (0.5 + Random 0.5);	
			} else {
				if (d_global_debug > 9) then { diag_log Format["(%1)[%2]: %3: %4",diag_tickTime,"spawnvehicles.sqf","Ignored Town - Player close",_name]; };
			};
		} foreach _eligible_towns;
		sleep (60 + random 60);
	};
};